package com.clougence.cloudcanal.dataprocess.datatransform.converter;

import java.io.IOException;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.net.URI;
import java.net.URL;
import java.sql.Types;
import java.util.Date;

import cn.hutool.core.util.URLUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.clougence.cloudcanal.dataprocess.datatransform.annotation.BuildAnnotation;
import com.clougence.cloudcanal.dataprocess.datatransform.common.*;
import com.clougence.cloudcanal.dataprocess.datatransform.model.GlanceRecordBO;
import com.clougence.cloudcanal.dataprocess.datatransform.model.GlanceRecordParam;
import com.clougence.cloudcanal.dataprocess.datatransform.model.OdsGlanceEventRecordBO;
import com.clougence.cloudcanal.sdk.api.modelv2.CustomFieldV2;
import com.clougence.cloudcanal.sdk.api.modelv2.CustomRecordV2;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

import static com.alibaba.fastjson.JSON.toJSONString;
import static com.clougence.cloudcanal.dataprocess.datatransform.common.GlanceRecordConstants.*;

/**
 * @author yongSen.wang
 * @date 2022/03/09 16:37
 */
public class DwdGlanceRecordConverter {

    public static GlanceRecordBO build(String source, CustomFieldV2 ipField,
                                       CustomFieldV2 timeField) {
        JSONObject sourceData = JSONObject.parseObject(source);

        String version = sourceData.getString(GlanceRecordConstants.Header.version);
        String screen = sourceData.getString(GlanceRecordConstants.Header.screen);
        String clientId = sourceData.getString(GlanceRecordConstants.Header.clientId);
        String deviceId = sourceData.getString(GlanceRecordConstants.Header.deviceId);
        String sessionId = sourceData.getString(GlanceRecordConstants.Header.sessionId);
        String unionId = sourceData.getString(GlanceRecordConstants.Header.unionId);
        String userId = sourceData.getString(GlanceRecordConstants.Header.userId);
        String utm = sourceData.getString(GlanceRecordConstants.Header.utm);
        String timezone = sourceData.getString(GlanceRecordConstants.Header.timezone);
        String userAgent = sourceData.getString(GlanceRecordConstants.Header.userAgent);
        String language = sourceData.getString(GlanceRecordConstants.Header.language);
        String network = sourceData.getString(GlanceRecordConstants.Header.network);
        String cpu = sourceData.getString(GlanceRecordConstants.Header.cpu);
        String title = sourceData.getString(GlanceRecordConstants.Header.title);
        String event = sourceData.getString(GlanceRecordConstants.Header.event);
        String url = sourceData.getString(GlanceRecordConstants.Header.url);
        long reqTime = sourceData.getLongValue(GlanceRecordConstants.Header.reqTime);
        String referrer = sourceData.getString(GlanceRecordConstants.Header.referrer);
        String utmData = sourceData.getString(GlanceRecordConstants.Header.utmData);
        String eventData = sourceData.getString(GlanceRecordConstants.Header.eventData);
        String country = sourceData.getString(GlanceRecordConstants.Header.country);
        String gbLang = sourceData.getString(GlanceRecordConstants.Header.gbLang);
        String env = sourceData.getString(GlanceRecordConstants.Header.env);
        String platform = sourceData.getString(GlanceRecordConstants.Header.platform);

        GlanceRecordBO glanceRecord = new GlanceRecordBO();
        glanceRecord.setVersion(version);
        glanceRecord.setScreen(screen);
        glanceRecord.setClientId(clientId);
        glanceRecord.setDeviceId(deviceId);
        glanceRecord.setSessionId(sessionId);
        glanceRecord.setUnionId(unionId);
        glanceRecord.setUnionCode("");
        glanceRecord.setUnionRequestNo("");
        if (StringUtils.isNotBlank(unionId)) {
            String[] unionStr = unionId.split("\\|");
            if (unionStr.length >= 2) {
                glanceRecord.setUnionCode(unionStr[0]);
                glanceRecord.setUnionRequestNo(unionStr[1]);
            }
        } else {
            if (StringUtils.isNotBlank(url)) {
                Map<String, String> map = UrlUtils.urlSplit(url);
                String union = map.get(GlanceRecordConstants.Header.union);
                String requestNo = map.get(GlanceRecordConstants.Header.refferNo);
                glanceRecord.setUnionCode(union);
                glanceRecord.setUnionRequestNo(requestNo);
            }
        }

        glanceRecord.setUserId(userId);
        glanceRecord.setUtm(utm);
        glanceRecord.setTimezone(timezone);
        glanceRecord.setLanguage(language);
        glanceRecord.setNetwork(network);
        glanceRecord.setCpu(cpu);
        glanceRecord.setTitle(title);
        glanceRecord.setEvent(event);
        glanceRecord.setTime(DateUtils.getNewFormatDateString(new Date(reqTime)));
        glanceRecord.setUtmData(utmData);
        glanceRecord.setEventData(eventData);
        glanceRecord.setCountry(country);
        glanceRecord.setGbLang(gbLang);
        glanceRecord.setEnv(env);
        glanceRecord.setPlatform(platform);
        glanceRecord.setSourceData(source);
        glanceRecord.setOrderId("");
        glanceRecord.setPaymentType("");
//        glanceRecord.setPayAmount(new BigDecimal("0"));
        glanceRecord.setPayNumber("");
        glanceRecord.setUserAgent(userAgent);
        glanceRecord.setAgentMobile(0);
        glanceRecord.setAgentBrowser("");
        glanceRecord.setAgentVersion("");
        glanceRecord.setAgentPlatform("");
        glanceRecord.setAgentOs("");
        glanceRecord.setAgentOsVersion("");
        glanceRecord.setAgentEngine("");
        glanceRecord.setAgentEngineVersion("");
        glanceRecord.setIp("");
        glanceRecord.setIpCountry("");
        glanceRecord.setIpRegion("");
        glanceRecord.setIpProvince("");
        glanceRecord.setIpCity("");
        glanceRecord.setIpIsp("");
        glanceRecord.setUrl(url);
        glanceRecord.setUrlHost("");
        glanceRecord.setUrlPath("");
        glanceRecord.setUrlHostPath("");
        glanceRecord.setReferrer(referrer);
        glanceRecord.setReferrerHost("");
        glanceRecord.setReferrerPath("");
        glanceRecord.setReferrerHostPath("");
        String utmSource = "";
        String utmMedium = "";
        Long utmTime = null;
        String utmCampaign = "";
        String utmTerm = "";
        if (StringUtils.isNotBlank(eventData)) {
            try {
                JSONObject json = JSONObject.parseObject(eventData);
                utmSource = json.getString(utm_source);
                utmMedium = json.getString(utm_medium);
                utmTime = json.getLongValue(utm_time);
                utmCampaign = json.getString(utm_campaign);
                utmTerm = json.getString(utm_term);
                glanceRecord.setOrderId(json.getString(ORDER_ID));
                glanceRecord.setPaymentType(json.getString(paymentType));
//                glanceRecord.setPayAmount(json.getBigDecimal(payAmount));
                glanceRecord.setPayNumber(json.getString(PAY_NUMBER));
                String eventUtmData = json.getString(EVENT_UTM_DATA);
                if (StringUtils.isBlank(utmSource) && StringUtils.isNotBlank(eventUtmData)) {
                    JSONObject eventDataJson = JSONObject.parseObject(eventUtmData);
                    utmSource = eventDataJson.getString(GlanceRecordConstants.Header.utmSource);
                    utmMedium = eventDataJson.getString(GlanceRecordConstants.Header.utmMedium);
                    utmTime = eventDataJson.getLongValue(utm_time);
                    utmCampaign = eventDataJson.getString(utm_campaign);
                    utmTerm = eventDataJson.getString(utm_term);
                }

            } catch (Exception ignored) {
            }
        }

        if (StringUtils.isBlank(utmSource) && StringUtils.isNotBlank(utmData)) {
            JSONObject data = JSONObject.parseObject(utmData);
            utmSource = data.getString(GlanceRecordConstants.Header.utmSource);
            utmMedium = data.getString(GlanceRecordConstants.Header.utmMedium);
            utmTime = data.getLongValue(utm_time);
            utmCampaign = data.getString(utm_campaign);
            utmTerm = data.getString(utm_term);
        }

        if (StringUtils.isBlank(utmSource) && StringUtils.isNotBlank(url)) {
            Map<String, String> map = UrlUtils.urlSplit(url);
            utmSource = map.get(GlanceRecordConstants.Header.utmSource);
            utmMedium = map.get(GlanceRecordConstants.Header.utmMedium);
            utmCampaign = map.get(utm_campaign);
            utmTerm = map.get(utm_term);
        }
        glanceRecord.setUtmSource(utmSource);
        glanceRecord.setUtmMedium(utmMedium);
        glanceRecord.setUtmCampaign(utmCampaign);
        glanceRecord.setUtmTerm(utmTerm);
        if (utmTime != null && utmTime != 0L) {
            glanceRecord.setUtmTime(DateUtils.getNewFormatDateString(new Date(utmTime)));
        }

        if (ipField != null) {
            String ip = String.valueOf(ipField.getValue());

            if (StringUtils.isNotBlank(ip)) {
                glanceRecord.setIp(ip);
                try {
                    String cityInfo = IpUtil.getCityInfo(ip);
                    if (StringUtils.isNotBlank(cityInfo)) {
                        String[] cityInfoArr = cityInfo.split("\\|");
                        glanceRecord.setIpCountry(cityInfoArr[0]);
                        glanceRecord.setIpRegion(cityInfoArr[1]);
                        glanceRecord.setIpProvince(cityInfoArr[2]);
                        glanceRecord.setIpCity(cityInfoArr[3]);
                        glanceRecord.setIpIsp(cityInfoArr[4]);
                    }
                } catch (Exception ignored) {
                }
            }
        }

        if (StringUtils.isNotBlank(userAgent)) {
            try {
                UserAgent ua = UserAgentUtil.parse(userAgent);
                if (ua != null) {
                    glanceRecord.setAgentMobile(ua.isMobile() ? 0 : 1);
                    glanceRecord.setAgentBrowser(ua.getBrowser().toString());
                    glanceRecord.setAgentVersion(ua.getVersion());
                    glanceRecord.setAgentPlatform(ua.getPlatform().toString());
                    glanceRecord.setAgentOs(ua.getOs().toString());
                    glanceRecord.setAgentOsVersion(ua.getOsVersion());
                    glanceRecord.setAgentEngine(ua.getEngine().toString());
                    glanceRecord.setAgentEngineVersion(ua.getEngineVersion());
                }
            } catch (Exception ignored) {
            }
        }

        if (StringUtils.isNotBlank(url)) {
            try {
                URI host = URLUtil.getHost(new URL(url));
                String path = URLUtil.getPath(url);
                glanceRecord.setUrlHost(host.getHost());
                glanceRecord.setUrlPath(path);
                glanceRecord.setUrlHostPath(host.getHost() + path);
            } catch (Exception ignored) {
            }
        }

        if (StringUtils.isNotBlank(referrer)) {
            try {
                URI host = URLUtil.getHost(new URL(referrer));
                String path = URLUtil.getPath(referrer);
                glanceRecord.setReferrerHost(host.getHost());
                glanceRecord.setReferrerPath(path);
                glanceRecord.setReferrerHostPath(host.getHost() + path);
            } catch (Exception ignored) {
            }
        }
        if (timeField != null) {
            try {
                glanceRecord.setStatisticsDate(DateUtils.getWebDateString(DateUtils.getDayBegin(
                    DateUtils.parseDateNewFormat(String.valueOf(timeField.getValue())))));
            } catch (Exception ignored) {
            }
        }
        return glanceRecord;

    }

    public static void buildCustomRecord(CustomRecordV2 recordV2, GlanceRecordBO glanceRecord) {
        if (recordV2 != null && glanceRecord != null) {
            try {
                Map<String, Object> map = JsonUtil.beanToMap(glanceRecord);
                map.forEach((k, v) -> {
                    try {
                        if (v != null) {
                            Field field = glanceRecord.getClass().getDeclaredField(k);
                            BuildAnnotation annotation = field.getAnnotation(BuildAnnotation.class);
                            String fieldName = annotation.fieldName();
                            int type = annotation.type();
                            CustomFieldV2 customField = CustomFieldV2.buildField(fieldName, v, type,
                                false, false, true);
                            recordV2.addField(customField);
                        }

                    } catch (Exception ignored) {
                    }
                });
            } catch (Exception ignored) {
            }
        }

    }

    public static void main(String[] args) {

        String bb = "{\n" + "\"client_id\" :\n" + "\"0503c08270a5041a51e4de88-02ef45-2e2576\",\n"
                    + "\"env\" :\n" + "\"prod\",\n" + "\"event\" :\n" + "\"utm_landing\",\n"
                    + "\"event_data\" :\n" + "{\n" + "\"utmData\" :\n" + "{\n" + "\"rfsn\" :\n"
                    + "\"5735037.594064\",\n" + "\"utm_medium\" :\n" + "\"aff\",\n"
                    + "\"utm_source\" :\n" + "\"refersion\"\n" + "}\n" + "},\n" + "\"gb_lang\" :\n"
                    + "\"en\",\n" + "\"language\" :\n" + "\"en-US\",\n" + "\"network\" :\n"
                    + "\"4g\",\n" + "\"referrer\" :\n" + "\"https://www.youtube.com/\",\n"
                    + "\"screen\" :\n" + "\"412x732\",\n" + "\"session_id\" :\n"
                    + "\"90fd98d7bbb4093e81e43389c2628f0d6a9e-1c9009-1d6453\",\n" + "\"time\" :\n"
                    + "1631799976870,\n" + "\"timezone\" :\n" + "-120,\n" + "\"title\" :\n"
                    + "\"Goboo Xiaomi Pad 5 Pre-order\",\n" + "\"url\" :\n"
                    + "\"https://www.goboo.com/ev/xiaomi-pad-5?rfsn=5735037.594064&utm_source=refersion&utm_medium=aff\",\n"
                    + "\"user_agent\" :\n"
                    + "\"Mozilla/5.0 (Linux; Android 11; Mi Note 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Mobile Safari/537.36\",\n"
                    + "\"version\" :\n" + "\"1.0.0\"\n" + "}";
        String cc = "{\n" + "\"client_id\" :\n" + "\"ff41b8dacacc2f719a4dd72e-4f4874-ec24b0\",\n"
                    + "\"country\" :\n" + "\"PT\",\n" + "\"device_id\" :\n"
                    + "\"a33a4dfe14bfc7634c40ac1e31c1ee1b\",\n" + "\"env\" :\n" + "\"prod\",\n"
                    + "\"event\" :\n" + "\"gb_pay_success\",\n" + "\"event_data\" :\n" + "{\n"
                    + "\"order_list\" :\n" + "[\n" + "\"0\" :\n" + "{ … }\n" + "],\n"
                    + "\"pay_number\" :\n" + "\"146533452233478144\"\n" + "},\n" + "\"gb_lang\" :\n"
                    + "\"de\",\n" + "\"language\" :\n" + "\"pt-PT\",\n" + "\"network\" :\n"
                    + "\"4g\",\n" + "\"screen\" :\n" + "\"360x640\",\n" + "\"session_id\" :\n"
                    + "\"6e220f20050ea703dc922ee840b99ee39cc2-19dcee-054db0\",\n" + "\"time\" :\n"
                    + "1646053484594,\n" + "\"title\" :\n" + "\"Pay successfully.\",\n"
                    + "\"url\" :\n"
                    + "\"https://www.goboo.com/payment/success?order_id=146533452233478144\",\n"
                    + "\"user_agent\" :\n"
                    + "\"Mozilla/5.0 (Linux; Android 9; VTR-L09 Build/HUAWEIVTR-L09; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/98.0.4758.101 Mobile Safari/537.36/goboo/null/goboo/null\",\n"
                    + "\"user_id\" :\n" + "\"217467\",\n" + "\"version\" :\n" + "\"1.0.0\"\n" + "}";
        //        OdsGlanceEventRecordBO record = buildData(bb);
        //        JSONObject sourceData = JSONObject.parseObject(bb);
        //        String user = sourceData.getString(USER_AGENT);
        //        UserAgent ua = UserAgentUtil.parse(user);
        //        System.out.println(JSON.toJSONString(ua));

        //        GlanceRecordParam param = JSON.parseObject(bb, GlanceRecordParam.class);
        //        GlanceRecordParam paramC = JSON.parseObject(cc, GlanceRecordParam.class);
        //        System.out.println(toJSONString(param));
        GlanceRecordBO glanceRecord = build(bb, null, null);
        System.out.println(toJSONString(glanceRecord));
    }
}
